package com.cuijq.virwallet.service;

import com.cuijq.virwallet.exception.NoSufficientBalanceException;
import com.cuijq.virwallet.repository.VirtualWalletRepository;
import com.cuijq.virwallet.repository.entity.VirtualWalletEntity;
import com.cuijq.virwallet.repository.entity.VirtualWalletTransactionEntity;
import com.cuijq.virwallet.service.bo.VirtualWallet;
import com.cuijq.virwallet.walletenum.Status;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

@Service
public class VirtualWalletService {

    @Autowired
    private VirtualWalletRepository walletRepo;
    @Autowired
    private VirtualWalletTransactionRepository transactionRepo;

    public VirtualWallet getVirtualWallet(Long walletId) {
        VirtualWalletEntity walletEntity = walletRepo.getWalletEntity(walletId);
        VirtualWallet wallet = convert(walletEntity);
        return wallet;
    }


    public BigDecimal getBalance(Long walletId) {
        return walletRepo.getBalance(walletId);
    }

    public void debit(Long walletId, BigDecimal amount) {
        VirtualWalletEntity walletEntity = walletRepo.getWalletEntity(walletId);
        VirtualWallet wallet = convert(walletEntity);
        wallet.debit(amount);
        walletRepo.updateBalance(walletId, wallet.balance());
    }

    public void credit(Long walletId, BigDecimal amount) {
        VirtualWalletEntity walletEntity = walletRepo.getWalletEntity(walletId);
        VirtualWallet wallet = convert(walletEntity);
        wallet.credit(amount);
        walletRepo.updateBalance(walletId, wallet.balance());
    }

    public void transfer(Long fromWalletId, Long toWalletId, BigDecimal amount) {
        VirtualWalletTransactionEntity transactionEntity = new VirtualWalletTransactionEntity();
        transactionEntity.setAmount(amount);
        transactionEntity.setCreateTime(System.currentTimeMillis());
        transactionEntity.setFromWalletId(fromWalletId);
        transactionEntity.setToWalletId(toWalletId);
        transactionEntity.setStatus(Status.TO_BE_EXECUTED);
        Long transactionId = transactionRepo.saveTransaction(transactionEntity);
        try {
            debit(fromWalletId, amount);
            credit(toWalletId, amount);
        } catch (Exception e) {
            transactionRepo.updateStatus(transactionId, Status.FAILED);
            e.printStackTrace();
        }
        transactionRepo.updateStatus(transactionId, Status.EXECUTED);
    }

    private VirtualWallet convert(VirtualWalletEntity walletEntity) {
        VirtualWallet virtualWalletBo = new VirtualWallet(walletEntity.getId());
        BeanUtils.copyProperties(walletEntity, virtualWalletBo);
        return virtualWalletBo;
    }
}

